# -*- coding: utf-8 -*-

"""
@author: david
@software: PyCharm
@file: mythread.py
@time: 2021/11/15 12:43
@desc:
"""
import threading
import time
import urllib
from datetime import date
from time import sleep

import serial
import wx

from bmp import ImageFile
from bmp2 import bmp_img_read_save_hist
from encode import encrypt_oracle, decrypt_oralce


class ThreadTime(threading.Thread):
    def __init__(self, frame, serial, com):
        """设置需要多线程运行的程序"""
        super(ThreadTime, self).__init__()  # 继承
        self.setDaemon(True)  # 设置为守护线程， 即子线程是守护进程，主线程结束子线程也随之结束。
        self.serial = serial
        self.frame = frame
        self.com = com
        self.m_serial = None

    def run(self):
        # # wx.CallAfter(self.frame.read, self.serial)
        # 存储bmp图片
        image = ImageFile()
        # m_data = image.getBMP('phone.bmp')

        while True:
            if self.serial is not None:
                try:
                    data = self.serial.read(self.serial.inWaiting())
                    # print('read...')
                    if data != b'':
                        if data.find(b'done\r\nOK\r\n') != -1:  # android 加载完成，发送回车，去掉版本信息
                            self.write(self.serial)
                            sleep(1)
                            data = self.serial.read(self.serial.inWaiting())
                            self.decode(data)
                        print(data)
                except Exception as e:
                    print("---异常---：", e)
                    self.serial = self.search()
            else:
                self.serial = self.search()

    def search(self):
        # # wx.CallAfter(self.frame.read, self.serial)
        is_find = False
        while True:
            m_serial = self.search_serial()
            if len(m_serial) > 0:
                for m in m_serial:
                    if m == self.com:  # 匹配到选定的串口
                        serial = self.open_port(self.com, 115200, None)
                        return serial
            sleep(1)

    def search_serial(self):
        m_list = []
        port_list = list(serial.tools.list_ports.comports())
        # print(port_list)
        if len(port_list) == 0:
            print('无可用串口')
            return m_list
        else:
            for i in range(0, len(port_list)):
                print(port_list[i])
                m_list.append(port_list[i][0])
            return m_list

    # 打开串口
    # 端口，GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
    # 波特率，标准值之一：50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
    # 超时设置,None：永远等待操作，0为立即返回请求结果，其他值为等待超时时间(单位为秒）
    def open_port(self, port, bps, timeout):
        ser = None
        try:
            # 打开串口，并得到串口对象
            ser = serial.Serial(port, bps, timeout=timeout)
        except Exception as e:
            print("---异常---：", e)
        return ser

    # 写数据
    def write(self, serial):
        result = serial.write('\r\n'.encode())  # 写数据
        print(result)

    # 解析字符串
    def decode(self, string):
        print(string)
        string = str(string, encoding="utf-8")
        # CPUID
        f_int = string.find('CPUID')
        CPUID = string[f_int:]
        CPUID_int = CPUID.find('\r\n\r')
        CPUID = CPUID[:CPUID_int]

        # MAC_LAN
        f_int = string.find('MAC_LAN')
        MAC_LAN = string[f_int:]
        MAC_LAN_int = MAC_LAN.find('\r\n\r')
        MAC_LAN = MAC_LAN[:MAC_LAN_int]

        # MAC_WLAN
        f_int = string.find('MAC_WLAN')
        MAC_WLAN = string[f_int:]
        MAC_WLAN_int = MAC_WLAN.find('\r\n\r')
        MAC_WLAN = MAC_WLAN[:MAC_WLAN_int]

        self.frame.m_textCtrl5.write(CPUID + '\r\n' + MAC_LAN + '\r\n' + MAC_WLAN + '\r\n')
        self.print_message(CPUID, MAC_LAN, MAC_WLAN)
        self.save(CPUID)

    def print_message(self, CPUID, MAC_LAN, MAC_WLAN):
        if self.frame.serial_print is not None:
            # 写入图片
            # m_data = bmp_img_read_save_hist('bmp')
            # self.frame.serial_print.write(
            #     "DOWNLOAD " + "phone.bmp," + len(m_data) + "," + m_data.encode("gb2312"))  # 写数据

            result = self.frame.serial_print.write(self.print_rcode(CPUID, MAC_LAN, MAC_WLAN).encode("gb2312"))  # 写数据
            print(result)

    def print_rcode(self, CPUID, MAC_LAN, MAC_WLAN):
        _batch_no = str(date.today())  # 当前日期
        batch_no = _batch_no.replace('-', '')
        cpuid = CPUID
        mac_lan = MAC_LAN
        mac_wlan = MAC_WLAN

        # text = 'PRODUCT_ID:MK-3\n' + cpuid + '\n' + mac_lan + '\n' + mac_wlan + '\nAPP_ID:1000\nBATCH_NO:' + batch_no
        text = 'PRODUCT_ID:MK-3\n' + cpuid + '\n' + 'APP_ID:1000\nBATCH_NO:' + batch_no
        entrypted_text = encrypt_oracle(text)
        print('加密：', entrypted_text)
        print('解密：', decrypt_oralce(entrypted_text))
        entrypted_text = urllib.parse.quote(entrypted_text)  # urlencode编码
        print('urlencode编码：', entrypted_text)

        # url = 'https://qrcode-h5.jsunet.cn/app/default?k=' + entrypted_text + '&appId=1000&SN=' + cpuid.replace('\n',
        #                                                                                                         '').replace('CPUID:','') + '&productId=MK-3'
        url = 'https://qrcode-h5.jsunet.cn/app/default?k=' + entrypted_text + '&productId=MK-3'
        # url = '12346'
        print('url: ', url)
        # self.write_rcode_bitmap(url)

        strPinterTmp = "SIZE 65 mm,20 mm\r\nGAP 2 mm\r\nCLS\r\nSPEED 1.5\r\nDENSITY 15\r\n"
        strPinterTmp += 'REFERENCE 0,0\r\n'  # 该指令用于定义卷标的参考坐标原点
        strPinterTmp += 'DIRECTION 1\r\n'  # 该指令用于定义打印时出纸和打印字体的方向
        strPinterTmp += 'QRCODE 535,20,M,4,A,0,'
        # strPinterTmp += '"' + CPUID +'\r\n' + MAC_LAN +'\r\n' + MAC_WLAN + '"' + '\r\n'
        strPinterTmp += '"' + url + '"' + "\r\n"
        # 打印字符串
        strPinterTmp += 'TEXT 60,45,"2",0,1,1,' + '"' + CPUID + '"' + '\r\n'
        strPinterTmp += 'TEXT 60,65,"2",0,1,1,' + '"' + MAC_LAN + '"' + '\r\n'
        strPinterTmp += 'TEXT 60,85,"2",0,1,1,' + '"' + MAC_WLAN + '"' + '\r\n'
        # 打印字符串
        m_msg = "售后咨询: 0 5 1 6 - 8 5 0 5 0 5 5 8"
        strPinterTmp += 'TEXT 60,170,"TSS24.BF2",0,1,2,' + '"' + m_msg + '"' + '\r\n'

        # strPinterTmp += 'PUTBMP 60,165,"phone.bmp"'

        strPinterTmp += "PRINT 1\r\n"
        print(strPinterTmp)
        return strPinterTmp

    def save(self, CPUID):
        """保存文本"""
        with open("CPUID.txt", "a") as f:
            f.write(CPUID + '\r\n')  # 自带文件关闭功能，不需要再写f.close()


class ThreadSerial(threading.Thread):
    def __init__(self, com):
        """设置需要多线程运行的程序"""
        super(ThreadSerial, self).__init__()  # 继承
        self.setDaemon(True)  # 设置为守护线程， 即子线程是守护进程，主线程结束子线程也随之结束。
        self.com = com
        self.m_serial = None

    def run(self):
        # # wx.CallAfter(self.frame.read, self.serial)
        is_find = False
        while True:
            print('while...')
            m_serial = self.serial()
            if len(m_serial) > 0:
                for m in m_serial:
                    if m == self.com:  # 匹配到选定的串口
                        self.m_serial = self.open_port(self.com, 115200, None)
                        is_find = True
                        break
                if is_find:
                    break
            if self.m_serial is not None:
                print('break')
                break

            sleep(1)

    def get_serial(self):
        return self.m_serial

    def serial(self):
        m_list = []
        port_list = list(serial.tools.list_ports.comports())
        # print(port_list)
        if len(port_list) == 0:
            print('无可用串口')
            return m_list
        else:
            for i in range(0, len(port_list)):
                print(port_list[i])
                m_list.append(port_list[i][0])
            return m_list

    # 打开串口
    # 端口，GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
    # 波特率，标准值之一：50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
    # 超时设置,None：永远等待操作，0为立即返回请求结果，其他值为等待超时时间(单位为秒）
    def open_port(self, port, bps, timeout):
        ser = None
        try:
            # 打开串口，并得到串口对象
            ser = serial.Serial(port, bps, timeout=timeout)
        except Exception as e:
            print("---异常---：", e)
        return ser
